#!/usr/bin/env ts-node
/**
 * Phase间门控验证脚本模板
 * 用于验证Phase间数据传递的一致性和完整性
 * 编译后的路径在；/scripts/validate-phase-gate.js
 */

import * as fs from 'fs';
import * as path from 'path';

interface RequirementFields {
  sources: Record<string, string>;
  fields: Record<string, {
    type: string;
    source: string;
    required: boolean;
    default: any;
    description?: string;
  }>;
  conflicts?: Array<{
    field: string;
    requirement: string;
    figma: string;
    resolution: string;
  }>;
}

interface BlueprintAligned {
  component: Record<string, any>;
  configurableProps: Array<{
    name: string;
    type: string;
    default: any;
    source: string;
    alignmentSource?: string;
    missingInFigma?: boolean;
  }>;
  alignmentSummary?: {
    totalFields: number;
    fromRequirement: number;
    fromFigma: number;
    conflicts: number;
  };
}

interface PropsContract {
  component: string;
  requirementAlignment: {
    source: string;
    alignmentRate: string;
    mappings: Record<string, string>;
  };
  structureDecision: {
    useStructure: string;
    reason: string;
    transformRequired: boolean;
  };
  props: Record<string, any>;
  transformers?: Record<string, any>;
}

class PhaseGateValidator {
  private componentName: string;
  private componentDir: string;

  constructor(componentName: string, componentDir?: string) {
    this.componentName = componentName;
    this.componentDir = componentDir || `./${componentName}`;
  }

  /**
   * 验证Phase0到Phase1的数据传递
   */
  validatePhase0to1(): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    try {
      // 读取Phase0产物
      const requirementFields = this.readJSON<RequirementFields>('phase0/requirement-fields.json');
      const executionContext = this.readJSON('phase0/execution-context.json');
      const componentDefinition = this.readJSON('phase0/component-definition.json');
      const qualityReport = this.readJSON('phase0/quality-report.json');

      // 验证requirement-fields存在
      if (!requirementFields || !requirementFields.fields) {
        errors.push('Phase0: requirement-fields.json缺失或无效');
      }

      // 验证execution-context包含必要信息
      if (!executionContext.figma?.fileKey || !executionContext.figma?.nodeId) {
        errors.push('Phase0: execution-context缺少Figma信息');
      }

      // 验证所有required字段都有定义
      for (const [fieldName, fieldDef] of Object.entries(requirementFields.fields || {})) {
        if (fieldDef.required && !fieldDef.default) {
          errors.push(`Phase0: 必需字段 ${fieldName} 缺少默认值`);
        }
      }

      // 验证component-definition中包含公共字段默认值
      const publicStandard = componentDefinition?.configArchitecture?.publicStandard || {};
      const publicFields = ['groupSetting', 'publishTime', 'expireTime'];
      for (const field of publicFields) {
        if (!(field in publicStandard)) {
          errors.push(`Phase0: component-definition缺少公共字段 ${field} 的默认值`);
        }
      }

      // 验证quality-report公共字段默认值记录
      if (!Array.isArray(qualityReport?.publicFieldDefaults) || qualityReport.publicFieldDefaults.length === 0) {
        errors.push('Phase0: quality-report缺少publicFieldDefaults记录');
      } else if (qualityReport.publicFieldDefaults.some((item: any) => item.default === undefined)) {
        errors.push('Phase0: quality-report存在default为undefined的公共字段');
      }

      if (qualityReport?.parameterCheck && Object.values(qualityReport.parameterCheck).includes('fail')) {
        errors.push('Phase0: parameterCheck存在失败条目');
      }

    } catch (error) {
      errors.push(`Phase0验证失败: ${error}`);
    }

    return { valid: errors.length === 0, errors };
  }

  /**
   * 验证Phase1到Phase2的数据传递
   */
  validatePhase1to2(): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    try {
      // 读取Phase1产物
      const blueprintAligned = this.readJSON<BlueprintAligned>('phase1/blueprint-aligned.json');
      const requirementFields = this.readJSON<RequirementFields>('phase0/requirement-fields.json');
      const figmaSemantics = this.readJSON('phase1/figma-semantics.json');

      // 验证所有requirement字段在blueprint中存在
      for (const fieldName of Object.keys(requirementFields.fields || {})) {
        const blueprintField = blueprintAligned.configurableProps.find(p => p.name === fieldName);
        if (!blueprintField) {
          errors.push(`Phase1: requirement字段 ${fieldName} 未在blueprint-aligned中`);
        }
      }

      // 验证figma-semantics包含面板、主题信息
      if (!Array.isArray(figmaSemantics?.contentPanels) || figmaSemantics.contentPanels.length === 0) {
        errors.push('Phase1: figma-semantics缺少contentPanels');
      }
      if (!Array.isArray(figmaSemantics?.stylePanels) || figmaSemantics.stylePanels.length === 0) {
        errors.push('Phase1: figma-semantics缺少stylePanels');
      }

      // 验证对齐摘要
      if (blueprintAligned.alignmentSummary) {
        const { fromRequirement, conflicts } = blueprintAligned.alignmentSummary;
        if (fromRequirement < Object.keys(requirementFields.fields || {}).length) {
          errors.push(`Phase1: 部分requirement字段未对齐 (${fromRequirement}/${Object.keys(requirementFields.fields || {}).length})`);
        }
        if (conflicts > 0) {
          errors.push(`Phase1: 存在${conflicts}个字段冲突未解决`);
        }
      }

      // 验证截图目录
      const screenshotsDir = path.join(this.componentDir, 'phase1', 'screenshots');
      if (!fs.existsSync(screenshotsDir)) {
        errors.push('Phase1: 缺少phase1/screenshots目录');
      } else {
        const pngFiles = fs.readdirSync(screenshotsDir).filter(f => f.endsWith('.png'));
        if (pngFiles.length === 0) {
          errors.push('Phase1: screenshots目录中没有PNG文件');
        }
      }

    } catch (error) {
      errors.push(`Phase1验证失败: ${error}`);
    }

    return { valid: errors.length === 0, errors };
  }

  /**
   * 验证Phase2到Phase3的数据传递
   */
  validatePhase2to3(): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    try {
      // 读取Phase2产物
      const propsContract = this.readJSON<PropsContract>('phase2/props-contract.json');
      const blueprintAligned = this.readJSON<BlueprintAligned>('phase1/blueprint-aligned.json');
      const qualityReport = this.readJSON('phase2/quality-report.json');
      const uiDiff = this.readJSON('phase2/ui-diff.json');

      // 验证props-contract包含所有blueprint字段
      for (const field of blueprintAligned.configurableProps) {
        if (!propsContract.props[field.name]) {
          // 检查是否有转换映射
          const hasTransform = propsContract.requirementAlignment?.mappings?.[field.name];
          if (!hasTransform) {
            errors.push(`Phase2: blueprint字段 ${field.name} 未在props-contract中`);
          }
        }
      }

      // 验证数据结构决策
      if (propsContract.structureDecision?.transformRequired) {
        if (!propsContract.transformers || Object.keys(propsContract.transformers).length === 0) {
          errors.push('Phase2: 需要转换但未定义transformers');
        }
      }

      // 验证对齐率（alignmentRate是0-1的浮点数）
      const alignmentRateRaw = propsContract.requirementAlignment?.alignmentRate ?? 0;
      const alignmentRate = typeof alignmentRateRaw === 'number'
        ? alignmentRateRaw
        : parseFloat(String(alignmentRateRaw));
      const alignmentPercent = alignmentRate * 100;
      if (alignmentPercent < 95) {
        errors.push(`Phase2: 对齐率低于95% (${alignmentPercent.toFixed(1)}%)`);
      }

      // 验证UI Diff与质量报告
      const uiDiffSkipped = uiDiff?.method === 'not_run';
      if (uiDiffSkipped) {
        if (!uiDiff?.skipReason) {
          errors.push('Phase2: ui-diff 标记not_run但缺少skipReason说明');
        }
      } else {
        if (typeof uiDiff?.similarity !== 'number' || uiDiff.similarity < 0.95) {
          errors.push(`Phase2: ui-diff相似度不足 (${uiDiff?.similarity ?? 0})`);
        }
        if (!String(uiDiff?.screenshot_base || '').includes('phase1/screenshots')) {
          errors.push('Phase2: ui-diff未引用phase1/screenshots基准');
        }
        if (!String(uiDiff?.screenshot_local || '').includes('phase2/screenshots')) {
          errors.push('Phase2: ui-diff未引用phase2/screenshots局部');
        }
      }

      if (qualityReport?.uiRestoration && qualityReport.uiRestoration < 0.95) {
        errors.push(`Phase2: quality-report记录uiRestoration=${qualityReport.uiRestoration}`);
      }
      if (qualityReport?.propsStructureValid === false) {
        errors.push('Phase2: quality-report propsStructureValid=false');
      }

    } catch (error) {
      errors.push(`Phase2验证失败: ${error}`);
    }

    return { valid: errors.length === 0, errors };
  }

  /**
   * 验证Phase3到Phase4的数据传递
   */
  validatePhase3to4(): { valid: boolean; errors: string[] } {
    const errors: string[] = [];

    try {
      // 读取Phase3产物
      const panelReuseAnalysis = this.readJSON('phase3/panel-reuse-analysis.json');
      const ragMatchDetails = this.readJSON('phase3/rag-match-details.json');
      const fieldTypeValidation = this.readJSON('phase3/field-type-validation.json');
      const needsCustomPanel = panelReuseAnalysis.analysis?.needsCustomPanel ?? panelReuseAnalysis.needsCustomPanel;

      if (!Array.isArray(ragMatchDetails?.entries) || ragMatchDetails.entries.length === 0) {
        errors.push('Phase3: rag-match-details.json缺少匹配记录');
      }

      const passRate = fieldTypeValidation?.summary?.passRate ?? 0;
      if (passRate < 1) {
        errors.push(`Phase3: field-type-validation通过率${(passRate * 100).toFixed(1)}%，禁止进入Phase4`);
      }

      const reuseString = panelReuseAnalysis.analysis?.reuseRate || panelReuseAnalysis.reuseRate || '0';
      const reuseRate = parseFloat(String(reuseString).replace('%', ''));
      if (reuseRate < 70) {
        errors.push(`Phase3: 面板复用率过低 (${reuseRate}%)`);
      }

      if (needsCustomPanel) {
        const customPanelSpec = this.readJSON('phase3/custom-panel-spec.json');
        if (!Array.isArray(customPanelSpec?.panels) || customPanelSpec.panels.length === 0) {
          errors.push('Phase3: 需要自定义面板但custom-panel-spec.json为空');
        }
      }

    } catch (error) {
      errors.push(`Phase3验证失败: ${error}`);
    }

    return { valid: errors.length === 0, errors };
  }

  /**
   * 验证Phase4到Phase5的数据传递
   */
  validatePhase4to5(): { valid: boolean; errors: string[] } {
    const errors: string[] = [];
    let panelReuseAnalysis: any = null;

    try {
      panelReuseAnalysis = this.readJSON('phase3/panel-reuse-analysis.json');

      // 如果需要自定义面板
      if (panelReuseAnalysis.needsCustomPanel) {
        const executionDecision = this.readJSON('phase4/execution-decision.json');
        const executionReport = this.readJSON('phase4/execution-report.json');
        const panelValidation = this.readJSON('phase4/panel-validation.json');

        if (!executionDecision || !executionDecision.executed) {
          errors.push('Phase4: 需要自定义面板但execution-decision.json表明未执行');
        }

        if (!executionReport || !executionReport.panels) {
          errors.push('Phase4: 需要自定义面板但execution-report.json缺失');
        }

        // 验证面板覆盖率
        if (executionReport?.fieldCoverage?.rate < 0.95) {
          errors.push(`Phase4: 面板字段覆盖率不足 (${(executionReport.fieldCoverage.rate * 100).toFixed(1)}%)`);
        }

        if (panelValidation?.fieldCoverage?.rate < 0.95) {
          errors.push(`Phase4: panel-validation字段覆盖率不足 (${(panelValidation.fieldCoverage.rate * 100).toFixed(1)}%)`);
        }
        if (panelValidation?.runtimeChecks && Object.values(panelValidation.runtimeChecks).includes('fail')) {
          errors.push('Phase4: 自定义面板运行时验证失败');
        }

        // 验证所有自定义面板字段都已实现
        const expectedPanels =
          panelReuseAnalysis.customPanelDetails ||
          panelReuseAnalysis.customPanelSpec?.panels ||
          [];
        if (expectedPanels.length > 0 && executionReport?.panels?.details) {
          for (const expectedPanel of expectedPanels) {
            const implementedPanel = executionReport.panels.details.find(
              (p: any) => p.panel === expectedPanel.panelName && p.status === 'implemented'
            );
            if (!implementedPanel) {
              errors.push(`Phase4: 期望的自定义面板 ${expectedPanel.panelName} 未实现`);
            }
          }
        }
      }

    } catch (error) {
      // Phase4可能被跳过，这是正常的
      if (panelReuseAnalysis?.needsCustomPanel) {
        errors.push(`Phase4验证失败: ${error}`);
      }
    }

    return { valid: errors.length === 0, errors };
  }

  /**
   * 运行所有验证
   */
  validateAll(): { phase: string; valid: boolean; errors: string[] }[] {
    const results = [];

    const phases = [
      { name: 'Phase0→1', validator: () => this.validatePhase0to1() },
      { name: 'Phase1→2', validator: () => this.validatePhase1to2() },
      { name: 'Phase2→3', validator: () => this.validatePhase2to3() },
      { name: 'Phase3→4', validator: () => this.validatePhase3to4() },
      { name: 'Phase4→5', validator: () => this.validatePhase4to5() }
    ];

    for (const phase of phases) {
      const result = phase.validator();
      results.push({
        phase: phase.name,
        ...result
      });

      // 如果某个Phase验证失败，停止后续验证
      if (!result.valid) {
        console.error(`${phase.name} 验证失败:`);
        result.errors.forEach(err => console.error(`  - ${err}`));
        break;
      } else {
        console.log(`${phase.name} 验证通过`);
      }
    }

    return results;
  }

  /**
   * 读取JSON文件
   */
  private readJSON<T = any>(filePath: string): T {
    const fullPath = path.join(this.componentDir, filePath);
    if (!fs.existsSync(fullPath)) {
      throw new Error(`文件不存在: ${fullPath}`);
    }
    const content = fs.readFileSync(fullPath, 'utf8');
    return JSON.parse(content);
  }
}

// CLI执行
if (require.main === module) {
  const args = process.argv.slice(2);
  const componentName = args[0];
  const phase = args[1];

  if (!componentName) {
    console.error('使用方法: ts-node validate-phase-gate.ts <组件名> [phase]');
    console.error('示例: ts-node validate-phase-gate.ts UsageTrendsProd2');
    console.error('     ts-node validate-phase-gate.ts UsageTrendsProd2 2-3');
    process.exit(1);
  }

  const validator = new PhaseGateValidator(componentName);

  if (phase) {
    // 验证特定Phase
    let result;
    switch (phase) {
      case '0-1':
      case 'P0':
        result = validator.validatePhase0to1();
        break;
      case '1-2':
      case 'P1':
        result = validator.validatePhase1to2();
        break;
      case '2-3':
      case 'P2':
        result = validator.validatePhase2to3();
        break;
      case '3-4':
      case 'P3':
        result = validator.validatePhase3to4();
        break;
      case '4-5':
      case 'P4':
        result = validator.validatePhase4to5();
        break;
      default:
        console.error(`未知的Phase: ${phase}`);
        process.exit(1);
    }

    if (result.valid) {
      console.log(`Phase${phase} 验证通过`);
    } else {
      console.error(`Phase${phase} 验证失败:`);
      result.errors.forEach(err => console.error(`  - ${err}`));
      process.exit(1);
    }
  } else {
    // 验证所有Phase
    const results = validator.validateAll();
    const allValid = results.every(r => r.valid);

    if (allValid) {
      console.log('\n所有Phase验证通过');
    } else {
      console.error('\n验证失败，请修复错误后重试');
      process.exit(1);
    }
  }
}

export { PhaseGateValidator };
